/*
 * Copyright 2008 Carnegie Mellon University
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package edu.cmu.lti.sepia.data.db;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import edu.cmu.lti.sepia.data.resource.ResourceManager;
import edu.cmu.lti.sepia.infra.topic.model.Task;
import edu.cmu.lti.sepia.task.setup.DBInitializer;
import edu.cmu.lti.sepia.util.ServletUtil;

/**
 * 
 * Manages Task object in a DB.
 * 
 * @see Task
 * @author Hideki Shima
 *
 */
public class TaskDAO {

	public static List<Task> getTasks( SQL sql ) throws SQLException {
		String query = Query.generate( Query.GET_TASKS, "" );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ResultSet rs = null;
		List<Task> tasks = new ArrayList<Task>();
		
		rs = sql.executeSelect(ps);
		if ( rs == null ) System.out.println( ps );
		while ( rs.next() ) tasks.add( rsToObject(rs) );

		rs.close();
		ps.close();

		return tasks;
	}
	
	public static void updateTask( SQL sql, Task task ) throws SQLException {
		String query = Query.generate( Query.UPDATE_TASK, "" );
		
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ps.setString(1, task.getTaskName());
		ps.setString(2, task.getTaskNameShort());
		ps.setString(3, task.getDescription());
		ps.setInt(   4, task.isMonolingual()?1:0);
		ps.setString(5, task.getSrcLang());
		ps.setString(6, task.getTrgLang());
		ps.setString(7, task.getTypesConcatenated());
		ps.setString(8, task.getTDLabelsConcatenated());
		ps.setString(9, task.getIRLabelsConcatenated());
		ps.setString(10, task.getSegmenterCmd());
		ps.setString(11, task.getIndices());
		ps.setInt(   12,task.getCurrentPhase());
		ps.setInt(   13,task.getTaskId());
		sql.execute(ps);
		ps.close();
	}
	
	// not used
	private static String addTask( SQL sql, Task task ) throws SQLException {	
		StringBuilder message = new StringBuilder();
		
		// Create Task DB
		String projectName = ResourceManager.p.getProperty("projectName");
		message.append( DBInitializer.createTaskDB( sql, projectName, task.getTaskNameShort() )+"\n" );
		
		// Add a new row in Task table in Shared DB 
		String query = Query.generate( Query.ADD_TASK, "" );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ps.setString(1, task.getTaskName());
		ps.setString(2, task.getTaskNameShort());
		ps.setString(3, task.getDescription());
		ps.setInt(   4, task.isMonolingual()?1:0);
		ps.setString(5, task.getSrcLang());
		ps.setString(6, task.getTrgLang());
		ps.setString(7, task.getTypesConcatenated());
		ps.setString(8, task.getTDLabelsConcatenated());
		ps.setString(9, task.getIRLabelsConcatenated());
		ps.setString(10, task.getSegmenterCmd());
		ps.setString(11, task.getIndices());
		ps.setInt(   12,task.getCurrentPhase());
		message.append( "Executing: "+ps.toString().replaceAll(".+: ", "")+"\n" );
		message.append( sql.executeInSilence(ps)+"\n" );
		ps.close();
		return message.toString();
	}
	
	public static String addTask( SQL sql, String taskNameShort ) throws SQLException {
		Task task = new Task( 0, "", taskNameShort, "",  0, "", "", "", "", "", "", "", 0 );
		return addTask( sql, task );
	}
	
	public static void deleteTaskByTaskNameShort( SQL sql, String taskNameShort ) throws SQLException {
		String query = Query.generate( Query.DELETE_TASK, "" );
		
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ps.setString(1, taskNameShort);
		sql.execute(ps);
		ps.close();
	}
	
	public static Task findByTaskNameShort( SQL sql, String taskNameShort ) throws SQLException {

		String query = Query.generate( Query.FIND_TASK_BY_NAME, "" );
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ResultSet rs = null;
		
		Task task = null;
		
		ps.setString(1, taskNameShort);
		rs = sql.executeSelect(ps);
		if ( rs.next() ) task = rsToObject(rs);
		rs.close();
		ps.close();
	
		return task;
	}
	
	public static Task findById( SQL sql, int taskId ) throws SQLException {
	  
	  String query = Query.generate( Query.FIND_TASK_BY_ID, "" );
	  PreparedStatement ps = sql.getConnection().prepareStatement(query);
	  ResultSet rs = null;
	  
	  Task task = null;
	  
	  ps.setInt(1, taskId);
	  rs = sql.executeSelect(ps);
	  if ( rs.next() ) task = rsToObject(rs);
	  rs.close();
	  ps.close();
	  
	  return task;
	}
	
	public static Task findLatest( SQL sql ) throws SQLException {
		String query = Query.generate( Query.FIND_LATEST_TASK, "" );
	    
		PreparedStatement ps = sql.getConnection().prepareStatement(query);
		ResultSet rs = null;
		Task task = null;
		
		rs = sql.executeSelect(ps);
		if ( rs.next() ) {
			task = rsToObject( rs );
		}
		rs.close();
		ps.close();
	
		return task;
	}
		
	private static Task rsToObject( ResultSet rs ) {
		try {
			Task task = new Task( rs.getInt(1), rs.getString(2),
					rs.getString(3), rs.getString(4), rs.getInt(5),
					rs.getString(6), rs.getString(7), rs.getString(8),
					rs.getString(9), rs.getString(10), rs.getString(11), 
					rs.getString(12), rs.getInt(13) );
			return task;
		} catch ( Exception e ) {
			e.printStackTrace();
			return null;
		}
	}

  public static JSONObject convertSingleTask( Task t ) throws JSONException {
    JSONObject j = new JSONObject();
    j.put("taskId", t.getTaskId());
    j.put("taskName", t.getTaskName());
    j.put("taskNameShort", t.getTaskNameShort());
    j.put("description", t.getDescription());
    j.put("isMonolingual", (t.isMonolingual()?1:0));
    j.put("srcLang", t.getSrcLang());
    j.put("trgLang", t.getTrgLang());
    j.put("types", t.getTypesConcatenated());
    j.put("irLabels", t.getIRLabelsConcatenated());
    j.put("tdLabels", t.getTDLabelsConcatenated());
    j.put("segmenterCmd", t.getSegmenterCmd());
    j.put("indriPath", t.getIndices());
    j.put("currentPhase", t.getCurrentPhase());
    return j;
  }

  public static JSONObject convertTask( Task t ) throws JSONException {
    List<Task> tasks = new ArrayList<Task>();
    tasks.add(t);
    return convertTasks(tasks);
  }
  
  public static JSONObject convertTasks( List<Task> tasks ) throws JSONException {
    JSONObject json = new JSONObject();
    JSONArray jsonArray = new JSONArray();
    for ( Task t : tasks ) {
      jsonArray.put(convertSingleTask(t));
    }
    json.put("tasks", jsonArray);
    return json;
  }
  
  public static Task parseRequest( HttpServletRequest request ) {
    if ( request.getParameter("taskNameShort")==null ) return null;
    
    ServletUtil s = new ServletUtil( request );
    
    return new Task( 
        s.readInt(   "taskId", -1),
        s.readString("taskName", ""),
        s.readString("taskNameShort", ""),
        s.readString("description", ""),
        s.readInt(   "isMonolingual", 1),
        s.readString("srcLang", ""),
        s.readString("trgLang", ""),
        s.readString("types", ""),
        s.readString("tdLabels", ""),
        s.readString("irLabels", ""),
        s.readString("segmenterCmd", ""),
        s.readString("indriPath", ""),
        s.readInt(   "currentPhase", -1)
    );
  }
    
}
